/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "sle_connect_hdi.h"
#include "sle_connect_config.h"
#include "sle_hal_errcode.h"
#include "sle_unit_test_log.h"
static SleConnectHdiCallbacks *g_connectHdiTestCbks = NULL;
static uint16_t g_connectId = 0;
static SleDeviceAddress g_addr = {
    .addrType = SLE_PUBLIC_ADDRESS_TYPE,
    .addr = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}
};

SleHdiErrorCode SleHdiConnectRemoteTest(const SleDeviceAddress *addr)
{
    g_connectHdiTestCbks->OnConnectStateChangedCb(g_connectId, addr, SLE_ACB_CONNECTED_STATE, SLE_PAIR_NONE_STATE, SLE_DISCONNECT_WITH_NONE);
    return SLE_HDI_ERRCODE_SUCC;
}

SleHdiErrorCode SleHdiDisconnectRemoteTest(const SleDeviceAddress *addr)
{
    g_connectHdiTestCbks->OnConnectStateChangedCb(g_connectId, addr, SLE_ACB_CONNECTED_STATE, SLE_PAIR_NONE_STATE, SLE_DISCONNECT_FOR_REMOTE);
    return SLE_HDI_ERRCODE_SUCC;
}

SleHdiErrorCode SleHdiUpdateConnectParamTest(const SleConnectionParamUpdate *params)
{
    SleConnectParam param = {
        .intervalMin = params->intervalMin,
        .intervalMax = params->intervalMax,
        .latency = params->maxLatency,
        .supervisionTimeout = params->supervisionTimeout,
    };
    SleConnectionParamUpdateEvt paramsEvt = {
        .interval = params->intervalMin,
        .latency = params->maxLatency,
        .supervisionTimeout = params->supervisionTimeout,
    };
    g_connectHdiTestCbks->OnConnectParamUpdateReqCb(g_connectId, SLE_HDI_ERRCODE_SUCC, &param);
    g_connectHdiTestCbks->OnConnectParamUpdateCb(g_connectId, SLE_HDI_ERRCODE_SUCC, &paramsEvt);
    return SLE_HDI_ERRCODE_SUCC;
}

SleHdiErrorCode SleHdiPairRemoteTest(const SleDeviceAddress *addr)
{
    SleAuthInfo authInfo;
    g_connectHdiTestCbks->OnPairCompleteCb(g_connectId, addr, SLE_HDI_ERRCODE_SUCC);
    g_connectHdiTestCbks->OnAuthCompleteCb(g_connectId, addr, SLE_HDI_ERRCODE_SUCC, &authInfo);
    g_connectHdiTestCbks->OnConnectStateChangedCb(g_connectId, addr, SLE_ACB_CONNECTED_STATE, SLE_PAIR_PAIRED_STATE, SLE_DISCONNECT_WITH_NONE);
    memcpy(&g_addr, addr, sizeof(SleDeviceAddress));
    return SLE_HDI_ERRCODE_SUCC;
}

SleHdiErrorCode SleHdiRemovePairedDeviceTest(const SleDeviceAddress *addr)
{
    g_connectHdiTestCbks->OnConnectStateChangedCb(g_connectId, &g_addr, SLE_ACB_CONNECTED_STATE, SLE_PAIR_NONE_STATE, SLE_DISCONNECT_WITH_NONE);
    return SLE_HDI_ERRCODE_SUCC;
}

SleHdiErrorCode SleHdiRemoveAllPairsTest(void)
{
    g_connectHdiTestCbks->OnConnectStateChangedCb(g_connectId, &g_addr, SLE_ACB_CONNECTED_STATE, SLE_PAIR_NONE_STATE, SLE_DISCONNECT_WITH_NONE);
    return SLE_HDI_ERRCODE_SUCC;
}

SleHdiErrorCode SleHdiGetPairedDevicesNumTest(uint16_t *number)
{
    *number = 1;
    return SLE_HDI_ERRCODE_SUCC;
}

SleHdiErrorCode SleHdiGetPairedDevicesTest(SleDeviceAddress *addr, uint16_t *number)
{
    *addr = g_addr;
    memcpy(addr, &g_addr, sizeof(SleDeviceAddress));
    *number = 1;
    return SLE_HDI_ERRCODE_SUCC;
}

SleHdiErrorCode SleHdiGetPairStateTest(const SleDeviceAddress *addr, SlePairState *state)
{
    *state = SLE_PAIR_PAIRED_STATE;
    return SLE_HDI_ERRCODE_SUCC;
}

SleHdiErrorCode SleHdiReadRemoteDeviceRssiTest(uint16_t connectId)
{
    g_connectHdiTestCbks->OnReadRssiCb(connectId, 0, SLE_HDI_ERRCODE_SUCC);
    return SLE_HDI_ERRCODE_SUCC;
}

SleHdiErrorCode SleHdiRegisterConnectCallbacksTest(const SleConnectHdiCallbacks *callback)
{
    g_connectHdiTestCbks = callback;
    return SLE_HDI_ERRCODE_SUCC;
}

SleHdiErrorCode GetSleConnectHdiOpts(SleConnectHdiOpts *connectOpts)
{
    SLE_UT_CHECK_AND_RETURN_RET(connectOpts != NULL, SLE_HDI_ERRCODE_FAIL);
    connectOpts->connectRemote = SleHdiConnectRemoteTest;
    connectOpts->disconnectRemote = SleHdiDisconnectRemoteTest;
    connectOpts->updateConnectParam = SleHdiUpdateConnectParamTest;
    connectOpts->sendPairReq = SleHdiPairRemoteTest;
    connectOpts->removePairDevice = SleHdiRemovePairedDeviceTest;
    connectOpts->removeAllPairs = SleHdiRemoveAllPairsTest;
    connectOpts->getPairedDevicesNum = SleHdiGetPairedDevicesNumTest;
    connectOpts->getPairedDevices = SleHdiGetPairedDevicesTest;
    connectOpts->getPairState = SleHdiGetPairStateTest;
    connectOpts->readRemoteRssi = SleHdiReadRemoteDeviceRssiTest;
    connectOpts->registerConnectCbks = SleHdiRegisterConnectCallbacksTest;
    return SLE_HDI_ERRCODE_SUCC;
}